//
//  MainWindowController.swift
//  iDev
//
//  Created by lbxia on 2021/8/22.
//

import Cocoa
import Carbon

class MainWindowController: NSWindowController, NSOpenSavePanelDelegate {

    var mouseX = 0;
    
    @IBOutlet weak var thumbailImageView: NSImageView!
    @IBOutlet weak var testLabel: NSTextField!
    override func windowDidLoad() {
        super.windowDidLoad()
        
        testLabel.stringValue = "dynamic text"
        
        print(DeviceInfo.getDeviceName())
        print(DeviceInfo.getDeviceIPAddress())
        print(DeviceInfo.getDeviceMacAddress())

        print(DeviceInfo.getIPAddr())
        
        /*
        let customview = CustomTableViewCell(frame: NSRect(x: 0, y: 0, width: 600, height: 60))
        
        let mview = MouseEventView(frame: NSRect(x: 0, y: 0, width: 600, height: 60))

        
        if let contentView = self.window?.contentView {
            
            contentView.addSubview(customview)
            
            customview.setBackgroundColor(NSColor.red)
                        
            customview.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                customview.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
                customview.topAnchor.constraint(equalTo: contentView.topAnchor),
                customview.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
                customview.heightAnchor.constraint(equalToConstant: 60)
            ])

            customview.addMonitorWithCase(.enteredAndExited)
//            customview.addMonitorWithCase(.moved)

            
            contentView.addSubview(mview)
            mview.setBackgroundColor(NSColor.blue)
            mview.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                mview.leadingAnchor.constraint(equalTo: customview.leadingAnchor),
                mview.topAnchor.constraint(equalTo: customview.bottomAnchor),
                mview.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
                mview.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
//                mview.heightAnchor.constraint(equalToConstant: 160)
            ])
//            mview.addMonitorWithCase(.enteredAndExited)
        }
        */
    }
    
    @IBAction func testinputMouseLocation(_ sender: Any) {
        
        //获取当前屏幕坐标
        print(NSEvent.mouseLocation.debugDescription)
        
//        InputMouseManage.testMouseInput()
    
//        InputKeyManage.testKeyboardInput()
        
        
        /*
         NSWorkspace
         https://www.jianshu.com/p/2a4309da201a
         https://www.jianshu.com/p/8ebf09a8cb9a
         
         CGWindow
        */
        
//        WindowManage.sharedManager().getWindowsInfoOnScreens()

        if let img = WindowManage.sharedManager().test() {
            self.thumbailImageView.image = img
        }

        
        
        //must be regeister notification
        //this code not response
//        NSWorkspace.shared.notificationCenter.post(name: NSNotification.Name.init(rawValue: "com.apple.expose.awake"), object: nil)
//        
//        DispatchQueue.main.asyncAfter(deadline: .now()+1) {
//
//            print(NSWorkspace.shared.frontmostApplication?.localizedName ?? "")
//            print(NSWorkspace.shared.frontmostApplication?.bundleIdentifier ?? "")
//
//
//            for app in NSWorkspace.shared.runningApplications {
//
//                
//                //dock有显示并是打开的应用程序，不然会包含所有无界面的，以及只有系统顶部，右边有图标的应用
//                if app.activationPolicy == .regular {
//                    
//                    //active一般只有一个，系统最上层显示的那个
//                    print((app.localizedName ?? "") + " bundleIdentifier :" + (app.bundleIdentifier ?? "") + " hidden: " + (app.isHidden ? "1" : "0") + " active: " + (app.isActive ? "active" : "unactive"))
//                    
//                    //                app.icon  应用程序图标？
//                    if let bid = app.bundleIdentifier, bid == "com.apple.Safari", let img = app.icon {
//                        
//                        self.thumbailImageView.image = img;
//                    }
//                }
//                
////               app.localizedName  当地名称
////               app.processIdentifier pid
//
//            }
//        }
        
        //其他app全部隐藏了
//        NSWorkspace.shared.hideOtherApplications()
        
        //启动其他app，也能达到激活的效果，将这个app放到最前端显示
        //也可携带参数打开，调用复杂功能，可能需要applescript去调用
//        NSWorkspace.shared.launchApplication("Safari")
        
//        NSWorkspace.shared.launchApplication(withBundleIdentifier: "com.apple.Safari", options: [], additionalEventParamDescriptor: nil, launchIdentifier: nil)
        
        //打开指定url
//        NSWorkspace.shared.open([URL(string: "https://www.baidu.com")!], withAppBundleIdentifier: "com.apple.Safari", options: [], additionalEventParamDescriptor: nil, launchIdentifiers: nil)
        
        
        //类似系统默认快捷键 control + 向上箭头 效果
//        NSWorkspace.shared.launchApplication("Mission Control")
        
        //打开启动台，没有关闭的功能，可以模拟鼠标移动到最左边，然后点击，最后恢复鼠标位置达到效果
//        NSWorkspace.shared.launchApplication("Launchpad")

        
        //触控板显示桌面效果，和F11快捷键一致
        

        //隐藏所有app，包含自身，达到显示桌面效果，不是触控板那种其他app散开的，然后显示桌面的效果
//        let apps = NSWorkspace.shared.runningApplications
//        for app in apps {
//            app.hide()
//        }
//        for win in NSApp.windows {
//            NSApp.hide(win)
//        }
        
        
//        self.keyboardKeyDown(key: 0x00)
//
//        guard self.availablePermissionWithAccessibility() else {
//            return
//        }
   
//        self.testMouseMove()
//        self.testKeyboardInput()
        
//        self.testCombineKeyInput()
        
//        self.testMouseInput()
       
    }
    
    
    
    /// 调试状态，可能过段时间，比如关机之类(或修改了代码等)，系统辅助里面已经显示勾选上的，
    /// 但是状态不对，需要手动删除了系统辅助里面的app，会重新生成，状态会更新正常
    /// 目前首次调用是判断没有权限，但是到系统辅助里面也看不到自己的app，一般需要先调用个触发系统权限功能？app内记录一下是否调用过，
    /// 未调用的可以调用个会触发提示得功能即可，如self.keyboardKeyDown(key: 0x00)
    func availablePermissionWithAccessibility() -> Bool {
        
        let opts = NSDictionary(object: kCFBooleanTrue!,
                                forKey: kAXTrustedCheckOptionPrompt.takeUnretainedValue() as NSString
                                ) as CFDictionary

        guard AXIsProcessTrustedWithOptions(opts) == true else
        {
            
            //https://blog.csdn.net/zzl819954692/article/details/97380443
            
            if #available(macOS 10.14, *), let url = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility") {
                NSWorkspace.shared.open(url)
                
                //Privacy_Assistive 文件或文件夹，实际无效果
                //Privacy_AllFiles 完全磁盘访问权限
                //Privacy_Accessibility 辅助功能
                return false
            }else{
                
                //10.14之前应该直接是有权限的
                return true
            }
        }
        
        return true
    }
    
    
    // MARK:  模拟鼠标输入
    
  
    //https://blog.csdn.net/weixin_41483813/article/details/82622742
    
    
    func testMouseInput()  {
        
        self.switch2RightDesktop()
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            
            self.switch2LeftDesktop()
        }
        
        return
        // trackpad事件系统没有提供支持，只能使用模拟 键盘快捷键类似效果
        
//        DispatchQueue.global().asyncAfter(deadline: .now()+3) {
//
//            self.mouseLeftClick(mouseDown: true)
////            self.mouseLeftClick(mouseDown: false)
//        }
//
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            
            
            //右键
//            self.mouseRightClick(mouseDown: true)
//            self.mouseRightClick(mouseDown: false)

            
            //尽量配对，否则可能会有小细节的问题
//            self.mouseLeftClick(mouseDown: true)
//            self.mouseLeftClick(mouseDown: false)
//
//            self.mouseLeftClick(mouseDown: true)
//            self.mouseLeftClick(mouseDown: false)
//
//            self.mouseLeftDoubleClick()
            
            
            //拖动 c语言
//            Thread.detachNewThread {
//
//                //开始前 click down
//                self.mouseLeftClick(mouseDown: true)
//
//                //模拟移动
//                var first = true
//                var mouseLoc = NSEvent.mouseLocation
//                mouseLoc.y = NSHeight(NSScreen.screens[0].frame) - mouseLoc.y;
//
//                for i in 1..<60{
//                    self.mouseX += i;
//
//                    self.mouseDrag(mouseLoc,CGFloat(1), 0,first)
//
//                    first = false
//
//                    Thread.sleep(forTimeInterval: 0.01)
//                }
//
//                //结束： click up
//                DispatchQueue.main.asyncAfter(deadline: .now()+1) {
//                    self.mouseLeftClick(mouseDown:false)
//
//                }
//            }
            
            // drag swift 语言
//            Thread.detachNewThread {
//
//                //开始前 click down
//                self.mouseLeftClick(mouseDown: true)
//
//                //模拟移动
//                var first = true
//
//                for i in 1..<60{
//                    self.mouseX += i;
//
//                    self.mouseLeftDrag(1, 1,first)
//
//                    first = false
//
//                    Thread.sleep(forTimeInterval: 0.01)
//                }
//
//                //结束： click up
//                DispatchQueue.main.asyncAfter(deadline: .now()+1) {
//                    self.mouseLeftClick(mouseDown:false)
//
//                }
//            }
            
            
            //上下滑动(鼠标齿轮效果)
//            Thread.detachNewThread {
//
//                for i in 1..<160{
//
//                    createScrollWheelEventY(Float(Int32((2))))
//
//                    Thread.sleep(forTimeInterval: 0.1/Double(i))
//                }
//            }
            
            //wheel swift版本
//            Thread.detachNewThread {
//
//                for i in 1..<160{
//
//                    //左右滑动
//                    self.mouseScrollWheel(dx: Int32(i), dy: 0, dz: 0)
//
//                    Thread.sleep(forTimeInterval: 0.1/Double(i))
//                }
//
//                Thread.sleep(forTimeInterval: 1)
//
//
//                for i in 1..<160{
//
//                    //上下滑动
//                    self.mouseScrollWheel(dx: 0, dy: Int32(i), dz: 0)
//
//                    Thread.sleep(forTimeInterval: 0.1/Double(i))
//                }
//            }
            
            //模拟trackpad手势，通过快捷键模拟
            self.ctrlAndArrow()
            
        }
        
    }
    
    func  testMouseMove()  {
        
        Thread.detachNewThread {
            
            for i in 1..<10000{
                self.mouseX += i;
                self.moveMouse(1, 0)
                Thread.sleep(forTimeInterval: 0.01)
            }
        }
    }
    
    func moveMouse(_ dx:CGFloat , _ dy:CGFloat){
        //先监控移动前鼠标位置
        var mouseLoc = NSEvent.mouseLocation
        mouseLoc.y = NSHeight(NSScreen.screens[0].frame) - mouseLoc.y;
        //计算鼠标新位置
        let newLoc = CGPoint(x: mouseLoc.x-CGFloat(dx), y: mouseLoc.y+CGFloat(dy))
        print("moving \(dx) \(dy)")
        CGDisplayMoveCursorToPoint(0, newLoc)
    }
    
    //swift drag
    func mouseLeftDrag(_ dx:CGFloat , _ dy:CGFloat, _ dragFirst: Bool = true)  {
        
        
        struct dragRecord{
            static var newLoc: CGPoint?
        }
        
        if dragFirst {
            
            //只会返回首次拖动的位置
            var mouseLoc = NSEvent.mouseLocation
            mouseLoc.y = NSHeight(NSScreen.screens[0].frame) - mouseLoc.y;
            
            dragRecord.newLoc = mouseLoc
        }
        
        let mouseLoc = dragRecord.newLoc!
       
        //计算鼠标新位置
        let newLoc = CGPoint(x: mouseLoc.x+CGFloat(dx), y: mouseLoc.y+CGFloat(dy))
        
        dragRecord.newLoc = newLoc
        
        guard let mouseEvent = CGEvent(mouseEventSource: nil,
                                       mouseType: .leftMouseDragged,
                                mouseCursorPosition: newLoc,
                                mouseButton: .left
                                ) else {return}
        
        mouseEvent.post(tap: .cghidEventTap)
       
    }
    
    
    //滚动 swift版本
    func mouseScrollWheel(dx: Int32 = 0, dy: Int32 = 0, dz: Int32 = 0)  {
        
//
        /*
         CGWheelCount wheelCount = 2; // 1 for Y-only, 2 for Y-X, 3 for Y-X-Z
         int32_t xScroll = −1; // Negative for right
         int32_t yScroll = −2; // Negative for down
         CGEventRef cgEvent = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, wheelCount, yScroll, xScroll);

         // You can post the CGEvent to the event stream to have it automatically sent to the window under the cursor
         CGEventPost(kCGHIDEventTap, cgEvent);

         NSEvent *theEvent = [NSEvent eventWithCGEvent:cgEvent];
         CFRelease(cgEvent);

         // Or you can send the NSEvent directly to a view
         [theView scrollWheel:theEvent];
         */
        if #available(macOS 10.13, *) {
            
            let wheelCount = dz != 0 ? 3 : 2
            
            
            let wheelEvent = CGEvent(scrollWheelEvent2Source: nil, units: CGScrollEventUnit.line, wheelCount: UInt32(wheelCount), wheel1: dy, wheel2: dx, wheel3: dz)
            
            
            
            wheelEvent?.post(tap: .cghidEventTap)

            
        } else {
            // Fallback on earlier versions
        }
        
    }
    
    
    /// 鼠标左键 按下或抬起，
    /// 问题：在编辑器里面编辑光标不会移动？(功能正常，由于当前在其他windows点击启动模拟功能，模拟点击第一次是次先切换到编辑器window,在模拟点击一次就编辑器位置就正常了)
    /// - Parameters:
    ///   - point: 鼠标按下位置，nil 表示取当前位置
    ///   - mouseDown: true->按下, false->抬起
    func mouseLeftClick(_ point: CGPoint? = nil, mouseDown: Bool = true)  {
        
        
        var tmp = point
        
        if tmp == nil {
            
            //先监控移动前鼠标位置
            var mouseLoc = NSEvent.mouseLocation
            mouseLoc.y = NSHeight(NSScreen.screens[0].frame) - mouseLoc.y
            tmp = mouseLoc
        }
        
        let mouseLoc = tmp!
        
        guard let mouseEvent = CGEvent(mouseEventSource: nil,
                                       mouseType: mouseDown ? .leftMouseDown : .leftMouseUp,
                                mouseCursorPosition: mouseLoc,
                                mouseButton: .left
                                ) else {return}
        
        mouseEvent.post(tap: .cghidEventTap)
       
    }
    
    func mouseLeftDoubleClick(_ point: CGPoint? = nil)  {
        
        
        var tmp = point
        
        if tmp == nil {
            
            //先监控移动前鼠标位置
            var mouseLoc = NSEvent.mouseLocation
            mouseLoc.y = NSHeight(NSScreen.screens[0].frame) - mouseLoc.y
            tmp = mouseLoc
        }
        
        let mouseLoc = tmp!
        
        guard let firstClickDownEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: mouseLoc, mouseButton: .left ) else {
            return
        }
        
        guard let firstClickUpEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: mouseLoc, mouseButton: .left ) else {
            return
        }
        
        guard let twoClickDownEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: mouseLoc, mouseButton: .left ) else {
            return
        }
        
        guard let twoClickUpEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: mouseLoc, mouseButton: .left ) else {
            return
        }
        
        firstClickDownEvent.setIntegerValueField(.mouseEventClickState, value: 1)
        firstClickDownEvent.post(tap: .cghidEventTap)
        
        firstClickUpEvent.setIntegerValueField(.mouseEventClickState, value: 1)
        firstClickUpEvent.post(tap: .cghidEventTap)
        
        twoClickDownEvent.setIntegerValueField(.mouseEventClickState, value: 2)
        twoClickDownEvent.post(tap: .cghidEventTap)
        
        twoClickUpEvent.setIntegerValueField(.mouseEventClickState, value: 2)
        twoClickUpEvent.post(tap: .cghidEventTap)
       
    }
   
    func mouseRightClick(_ point: CGPoint? = nil, mouseDown: Bool = true)  {
        
        
        var tmp = point
        
        if tmp == nil {
            
            //先监控移动前鼠标位置
            var mouseLoc = NSEvent.mouseLocation
            mouseLoc.y = NSHeight(NSScreen.screens[0].frame) - mouseLoc.y
            tmp = mouseLoc
        }
        
        let mouseLoc = tmp!
        
        guard let mouseEvent = CGEvent(mouseEventSource: nil,
                                       mouseType: mouseDown ? .rightMouseDown : .rightMouseUp,
                                mouseCursorPosition: mouseLoc,
                                mouseButton: .left
                                ) else {return}
        
        mouseEvent.post(tap: .cghidEventTap)
       
    }
    
    // MARK: - 模拟键盘输入
    
    func testKeyboardInput()  {
        
        //需要系统允许app使用辅助功能，首次会提示权限，点击打开，会跳转到 设置->安全与隐私->辅助功能
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            
            self.keyboardKeyDown(key: 0x00)
            self.keyboardKeyDown(key: 0x01)

 
        }
    }
    
    
    func testCombineKeyInput()  {
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            
            self.keyboardCombine(virtualKey: 0x08, combineFlag: .maskCommand)
            //测试不调用 up ,功能正常
            self.keyboardCombine(virtualKey: 0x08, combineFlag: .maskCommand, keyDown: false)

        }
    }
    
    func ctrlAndArrow()  {
        
        
  
        
        struct structControl{
            static var keyCode: Int16 = 0x7B
        }
        //快捷键用户可自行设置，所以需要能读取快捷键？
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

            self.install()

            let str = String(structControl.keyCode)
//            self.exectueScript()
            
            self.exectueControlScript(str)
            structControl.keyCode += 1
        }
        
       
        
        //ctrl + 箭头没反应，不知道是否系统限制？ 应该可以通过 Applescript 来完成 ctrl + 箭头快捷键
                
//        let source = CGEventSource(stateID: CGEventSourceStateID.combinedSessionState)
//
//        if  let cmd_c_D = CGEvent(keyboardEventSource: source, virtualKey: CGKeyCode(KeyVirtualAssist.kVK_RightArrow.rawValue) , keyDown: true){
//            cmd_c_D.flags = .maskControl;
//
//            cmd_c_D.post(tap: .cghidEventTap)
//
//            print("command c")
//        }

        
        
        
        //各种F键无效 应该 system event 没有权限
//        let source = CGEventSource(stateID: CGEventSourceStateID.combinedSessionState)
//
//        if  let cmd_c_D = CGEvent(keyboardEventSource: source, virtualKey: CGKeyCode(KeyVirtualAssist.kVK_F3.rawValue) , keyDown: true){
//            cmd_c_D.flags = .maskCommand;
//
//            cmd_c_D.post(tap: .cghidEventTap)
//
//            print("command c")
//        }
        
        
        //放大 可以
//        let source = CGEventSource(stateID: CGEventSourceStateID.combinedSessionState)
//
//        if  let cmd_c_D = CGEvent(keyboardEventSource: source, virtualKey: CGKeyCode(KeyVirtualKey.kVK_ANSI_Equal.rawValue) , keyDown: true){
//            cmd_c_D.flags = CGEventFlags(rawValue: CGEventFlags.maskAlternate.rawValue | CGEventFlags.maskCommand.rawValue )
//            cmd_c_D.post(tap: .cghidEventTap)
//
//            print("command c")
//        }
        

        //缩小 可以
//        let source = CGEventSource(stateID: CGEventSourceStateID.combinedSessionState)
//        if  let cmd_c_D = CGEvent(keyboardEventSource: source, virtualKey: CGKeyCode(KeyVirtualKey.kVK_ANSI_Minus.rawValue) , keyDown: true){
//            cmd_c_D.flags = CGEventFlags(rawValue: CGEventFlags.maskAlternate.rawValue | CGEventFlags.maskCommand.rawValue )
//            cmd_c_D.post(tap: .cghidEventTap)
//
//            print("command c")
//        }
        
        
        //多个辅助键 模拟成功
//        let source = CGEventSource(stateID: CGEventSourceStateID.combinedSessionState)
//
//        if  let cmd_c_D = CGEvent(keyboardEventSource: source, virtualKey: CGKeyCode(KeyVirtualKey.kVK_ANSI_I.rawValue) , keyDown: true){
//            cmd_c_D.flags = CGEventFlags(rawValue: CGEventFlags.maskAlternate.rawValue | CGEventFlags.maskCommand.rawValue )
//            cmd_c_D.post(tap: .cghidEventTap)
//
//            print("command c")
//        }        
        
    }
    
    
    /// 模拟键盘输入
    /// - Parameters:
    ///   - key: 虚拟键值
    ///   - keyDown: true->按下按键 false:松开按键
    func keyboardInputKey(key: CGKeyCode, keyDown: Bool = true) {
        
        let source = CGEventSource(stateID: CGEventSourceStateID.hidSystemState)
        let event = CGEvent(keyboardEventSource: source, virtualKey: key, keyDown: keyDown)
        event?.post(tap: CGEventTapLocation.cghidEventTap)
        print("key \(key) is \(keyDown ? "down": "up")")
    }
    
    //按下按键
    func keyboardKeyDown(key: CGKeyCode) {
        
        let source = CGEventSource(stateID: CGEventSourceStateID.hidSystemState)
        let event = CGEvent(keyboardEventSource: source, virtualKey: key, keyDown: true)
        event?.post(tap: CGEventTapLocation.cghidEventTap)
        print("key \(key) is down")
    }
    
    //松开按键
    func keyboardKeyUp(key: CGKeyCode) {
        let source = CGEventSource(stateID: CGEventSourceStateID.hidSystemState)
        let event = CGEvent(keyboardEventSource: source, virtualKey: key, keyDown: false)
        event?.post(tap: CGEventTapLocation.cghidEventTap)
        print("key \(key) is released")
    }
    
   
    
    
    /// 组合按键
    /// - Parameters:
    ///   - virtualKey:  键的码值
    ///   - combineFlag: 组合键，如 command
    ///   - keyDown: true 表示键按下，false表示键up
    func keyboardCombine(virtualKey: CGKeyCode, combineFlag: CGEventFlags, keyDown: Bool = true)  {
        
        
        if  let cmd_c_D = CGEvent(keyboardEventSource: nil, virtualKey: virtualKey, keyDown: keyDown){
            cmd_c_D.flags = combineFlag;
            cmd_c_D.post(tap:.cghidEventTap)
            print("command c")
        }
    }
    
    // MARK: applescript
    func check() -> Bool {
        
        let scriptName  = "control"

        let path = NSSearchPathForDirectoriesInDomains(.applicationScriptsDirectory, .userDomainMask, true)[0]
        let file = "\(path)/\(scriptName).scpt"
        return FileManager.default.fileExists(atPath: file)
    }
    
    func install() {

        if !check() {

            let panel = NSSavePanel()
            panel.title = "保存AppleScript"
            panel.message = "请保存AppleScript文件至Application Scripts目录才可使用"
            //        panel.allowedFileTypes = ["json"]
            
            
            //必须最终保存的文件的名字
            let scriptName  = "control"
            panel.nameFieldStringValue = "\(scriptName).scpt"
            panel.directoryURL = FileManager.default.urls(for: .applicationScriptsDirectory, in: .userDomainMask)[0]
            panel.canCreateDirectories = false
            panel.delegate = nil

            if panel.runModal() == .OK {
                if let url = panel.url {
                    //  这里是你的项目的脚本的resource文件
                    if let resourceUrl = Bundle.main.url(forResource: scriptName, withExtension: "scpt") {
                        do {
                            let data = try Data(contentsOf: resourceUrl)
                            //测试换文件，没有权限，会写入失败
                            try data.write(to: url)
                            return

                        } catch {
                            panel.cancel(nil)
                            install()
                            return
                        }
                    }
                }
            }
            panel.cancel(nil)
            install()
        }
    }
    
    func  exectueScript()  {
        
        
//        NSPasteboard.general.setString("124", forType: NSPasteboard.PasteboardType.string)
        
        let pboard = NSPasteboard.general
        pboard.declareTypes([.string], owner: nil)
        pboard.setString("124", forType: .string)
    
        
        var dict:NSDictionary?
                
        var dir = FileManager.default.urls(for: .applicationScriptsDirectory, in: .userDomainMask)[0]
        
        let scriptName  = "control"

        dir.appendPathComponent("\(scriptName).scpt")
                
        let script = NSAppleScript(contentsOf: dir, error: &dict)
        script?.executeAndReturnError(&dict)
                
        print(dict)
    }
    
    func  exectueControlScript(_ str: String)  {
        
        let pboard = NSPasteboard.general
        pboard.declareTypes([.string], owner: nil)
        pboard.setString(str, forType: .string)
    
        
        var dict:NSDictionary?
                
        var dir = FileManager.default.urls(for: .applicationScriptsDirectory, in: .userDomainMask)[0]
        
        let scriptName  = "control"

        dir.appendPathComponent("\(scriptName).scpt")
                
        let script = NSAppleScript(contentsOf: dir, error: &dict)
        script?.executeAndReturnError(&dict)
                
        print(dict)
    }
    
    
    func switch2RightDesktop()  {
        
        self.executeAppleScriptWithControl(keyCode: UInt16(kVK_RightArrow))
    }
    
    func switch2LeftDesktop()  {
        
        self.executeAppleScriptWithControl(keyCode: UInt16(kVK_LeftArrow))
    }
    
    func executeAppleScriptWithControl(keyCode: UInt16)  {
        
        //从剪贴板复制内容
//        let scriptSource = "tell application \"System Events\"\rset KeyCode to (the clipboard as text)\r key code KeyCode using {control down}\r end tell"
        
//查看右边桌面
//        let scriptSource = "tell application \"System Events\"\r key code 124 using {control down}\r end tell"
        
        
        let scriptSource = "tell application \"System Events\"\r key code \(keyCode) using {control down}\r end tell"
        
        if let script = NSAppleScript(source: scriptSource){
            
             let eventDescriptor = script.executeAndReturnError(nil)
                
            print(eventDescriptor.stringValue ?? "")
            
        }


    }
}
